package main

import (
	"fmt"
	"net/http"
	"net/http/httputil"
)

func main() {
	request, err := http.NewRequest(http.MethodGet, "http://www.zhenai.com/zhenghun/aba", nil)
	request.Header.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36")
	request.Close = true
	client := http.Client{
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			fmt.Println("Redirect", req)
			return nil
		},
	}
	resp, err := client.Do(request)
	//resp, err := http.Get("http://www.baidu.com")
	if err != nil {
		panic(err)
	}
	// 在解决问题之前需要了解关于go是如何实现connection的一些背景小知识：
	// 有两个协程，一个用于读，一个用于写（就是readLoop和writeLoop）。
	// 在大多数情况下，readLoop会检测socket是否关闭，并适时关闭connection。
	// 如果一个新请求在readLoop检测到关闭之前就到来了，那么就会产生EOF错误并中断执行，而不是去关闭前一个请求。
	// 这里也是如此，我执行时建立一个新的连接，这段程序执行完成后退出，再次打开执行时服务器并不知道我已经关闭了连接，所以提示连接被重置；
	// 如果我不退出程序而使用for循环多次发送时，旧连接未关闭，新连接却到来，会报EOF。
	defer resp.Body.Close() // 如果不加这行会报EOF错误

	s, err := httputil.DumpResponse(resp, true) // 打印response
	if err != nil {
		panic(err)
	}
	fmt.Printf("%s\n", s)
}
